﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace XChip_Common
{
    public class Setting2FlashE2prom
    {
        #region  全局变量
        private static UInt16 I2C_addr = 0x36; //IIC地址，初始为36
        private static UInt16 I2C_mode = 1;        //IIC模式
        private static UInt16 duxin_mode = 1;      //度信模式
        private static UInt16 ISP_top = 0x50;
        private static int Model;
        private static UInt32 E2promMode;
        private static bool Usage;
        private static bool IsNoKey;
        private static bool I2cLianXie;

        //private static bool checkNum = true; //0xfff5 里面的一个开关
        //private static UInt16 checkNumTemp = 0;
        /// <summary>
        /// crc 全局变量
        /// </summary>
        static UInt16[] crc16_table ={
          0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
          0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
          0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
          0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
          0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
          0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
          0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
          0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
          0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
          0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
          0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
          0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
          0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
          0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
          0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
          0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
          0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
          0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
          0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
          0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
          0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
          0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
          0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
          0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
          0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
          0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
          0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
          0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
          0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
          0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
          0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
          0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78,
          };


        //public static uint XCHIP_ID = 0x58430151;
        public static uint XCHIP_ID = 0x51014358;

        //public Setting2FlashE2prom() { }


        #endregion

        #region header转Flash 或者e2pro
        /// <summary>
        /// header转Flash 或者e2pro
        /// </summary>
        /// <param name="inputfile">输入文件</param>
        /// <param name="outputfile">输出文件</param>
        /// <param name="model">0: EEPROM mode  1: Flash mode</param>
        /// <param name="e2prommode">e2prom mode 开始 addr</param>
        public static void FlashHeader2Flash(string inputfile, string outputfile, int model = 1, uint e2prommode = 0x0)
        {
            if (string.IsNullOrEmpty(inputfile))
            {
                return;
            }
            var listFile = ReadTextFileToList(inputfile);
            List<byte> listByte = new List<byte>();
            foreach (var item in listFile)
            {
                if (!string.IsNullOrEmpty(item))
                {
                    string temp = item.Contains("//") ? item.Remove(item.IndexOf("//")) : item;//移除注释
                    //if (temp.Contains("//"))
                    //{
                    //    var index = item.IndexOf("//");
                    //    temp = item.Remove(index);
                    //}
                    var listReg = Regex16ToString(temp);
                    if (listReg.Count == 2)
                    {
                        listByte.Add((byte)Convert.ToUInt32(listReg[1], 16));
                    }

                }

            }
            if (listByte.Count % 4 != 0)
            {
                int alignment = 4 - (listByte.Count % 4);
                for (int i = 0; i < alignment; i++)
                {
                    listByte.Add(0x00);
                }
            }
            UInt16 crc_check = XchipCrcCheck16(0xFFFF, listByte.ToArray());
            uint crc_Reg = (uint)((0xfffc << 16) + crc_check);
            string strreg = crc_Reg.ToString("X8");
            string str1 = strreg.Substring(0, 2);
            string str2 = strreg.Substring(2, 2);
            string str3 = strreg.Substring(4, 2);
            string str4 = strreg.Substring(6);
            string newReg = str4 + str3 + str2 + str1;
            crc_Reg = (uint)Convert.ToInt32(newReg, 16);
            List<uint> listUint = new List<uint>();
            for (int i = 0; i < listByte.Count / 4; i++)
            {
                var hig1 = (Convert.ToUInt32(listByte[i * 4]) << 24);
                var hig2 = (Convert.ToUInt32(listByte[i * 4 + 1]) << 16);
                var low1 = (Convert.ToUInt32(listByte[i * 4 + 2]) << 8);
                var low2 = Convert.ToUInt32(listByte[i * 4 + 3]);
                long temp = hig1 + hig2 + low1 + low2;
                listUint.Add(Convert.ToUInt32(temp));
            }

            if (model == 0)
            {
                //var crc_Reg = (0xfffc << 16) + crc_check;
                listByte.Add((byte)Convert.ToUInt32((crc_Reg >> 24) & 0xff));
                listByte.Add((byte)Convert.ToUInt32((crc_Reg >> 16) & 0xff));
                listByte.Add((byte)Convert.ToUInt32((crc_Reg >> 8) & 0xff));
                listByte.Add((byte)Convert.ToUInt32((crc_Reg) & 0xff));
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < listByte.Count; i++)
                {
                    sb.Append($"0x{(i + e2prommode).ToString("x4")},0x{listByte[i].ToString("x2")},\n");
                }
                File.WriteAllText(outputfile, sb.ToString());
            }
            else
            {
                listUint.Add(crc_Reg);
                StringBuilder sb = new StringBuilder();
                foreach (var item in listUint)
                {
                    sb.Append($"0x{item.ToString("x8")},\n");
                }
                File.WriteAllText(outputfile, sb.ToString());
            }
        }

        public static void CreatNewSmall(string s_oldPath, string outputfile)
        {
            var listFile = ReadTextFileToList(s_oldPath);
            List<ISPReg> listByte = new List<ISPReg>();
            List<uint> bootSet = new List<uint>();//模式不同
            string newstr = "";
            foreach (var item in listFile)
            {
                if (!string.IsNullOrEmpty(item))
                {
                    string aa = item.ToString();
                    string cc = aa.Substring(0, 2);
                    string cc1 = aa.Substring(2, 2);
                    string cc11 = aa.Substring(4, 2);
                    string cc111 = aa.Substring(6, 2);
                    string cc1111 = aa.Substring(8, 2);
                    string cc11111 = aa.Substring(10);
                    newstr += cc + cc1111 + cc111 + cc11 + cc1 + cc11111 + "\r\n";
                }
            }
            File.WriteAllText(outputfile, newstr);
        }


        #endregion

        #region PUCT转Flash 
        /// <summary>
        /// PUCT转Flash 
        /// </summary>
        /// <param name="inputfile">输入文件</param>
        /// <param name="outputfile">输出文件</param>
        public static void FlashPUCTFlash(string inputfile, string outputfile)
        {
            if (string.IsNullOrEmpty(inputfile))
            {
                return;
            }
            var listFile = ReadTextFileToList(inputfile);
            List<string> listByte = new List<string>();
            foreach (var item in listFile)
            {
                if (!string.IsNullOrEmpty(item))
                {
                    string temp = item.Contains("//") ? item.Remove(item.IndexOf("//")) : item;//移除注释
                    //if (temp.Contains("//"))
                    //{
                    //    var index = item.IndexOf("//");
                    //    temp = item.Remove(index);
                    //}
                    var listReg = Regex16ToString(temp);
                    if (listReg.Count == 2)
                    {
                        listByte.Add(listReg[1]);
                    }

                }

            }
            if (listByte.Count % 4 != 0)
            {
                int alignment = 4 - (listByte.Count % 4);
                for (int i = 0; i < alignment; i++)
                {
                    listByte.Add("00");
                }
            }
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < listByte.Count /4; i++)
            {

                sb.Append(string.Format("{0}{1}{2}{3},\n", listByte[(4 * i)], listByte[(4 * i) + 1], listByte[(4 * i) + 2], listByte[(4 * i) + 3]));
                
            }
            File.WriteAllText(outputfile, sb.ToString());
            //if (model == 0)
            //{

            //    StringBuilder sb = new StringBuilder();
            //    for (int i = 0; i < listByte.Count; i++)
            //    {
            //        sb.Append($"0x{(i + e2prommode).ToString("x4")},0x{listByte[i].ToString("x2")},\n");
            //    }
            //    File.WriteAllText(outputfile, sb.ToString());
            //}
            //else
            //{

            //    StringBuilder sb = new StringBuilder();
            //    foreach (var item in listUint)
            //    {
            //        sb.Append($"0x{item.ToString("x8")},\n");
            //    }
            //    File.WriteAllText(outputfile, sb.ToString());
            //}
        }


        #endregion

        #region Setting转Flash 或者e2pro

        /// <summary>
        /// Setting转Flash 或者e2pro
        /// </summary>
        /// <param name="inputfile">输入文件</param>
        /// <param name="outputfile">输出文件</param>
        /// <param name="model">0: EEPROM mode  1: Flash mode</param>
        /// <param name="e2prommode">e2prom mode 开始 addr</param>
        /// <param name="Usage">0 ：Usage scenarios:FPGA   1：Usage scenarios:CHIP</param>
        /// <param name="isNoKey">0：不忽略 1：忽略关键字</param>
        /// <param name="i2clianxie">0：不i2c连写模式 1：i2c连写模式</param>
        public static void FlashSetting2Flash(string inputfile, string outputfile, int _model = 1, uint _e2prommode = 0x0, int _usage = 1, int _isNoKey = 0, int _i2clianxie = 0,uint setHex =0x0)
        {
            if (string.IsNullOrEmpty(inputfile))
            {
                return;
            }
            Model = _model;
            E2promMode = _e2prommode;
            Usage = _usage == 0 ? true : false;
            IsNoKey = _isNoKey == 0 ? false : true;
            I2cLianXie = _i2clianxie == 0 ? false : true;


            I2C_addr = 0x36; //IIC地址，初始为36
            I2C_mode = 1;        //IIC模式
            duxin_mode = 1;      //度信模式
            ISP_top = 0x50;
            //checkNum = true; //0xfff5 里面的一个开关
            //checkNumTemp = 0;


            //

            //string bin_str = "";
            //byte[] binchar = new byte[] { };
            //int file_len;
            //FileStream fileStream = new FileStream(inputfile, FileMode.Open);
            ////读二进制文件类
            //BinaryReader br = new BinaryReader(fileStream, Encoding.UTF8);
            ////获取bin文件长度
            //file_len = (int)fileStream.Length;
            ////得到所有字节
            //binchar = br.ReadBytes(file_len);
            ////累加每字节数组转字符串
            //foreach (byte j in binchar)
            //{
            //    bin_str += "0x" + j.ToString("X2") + " ";
            //}
            ////关闭 BinaryReader 对象和基础流
            //br.Close();

            var listFile = ReadTextFileToList(inputfile);
            List<ISPReg> listByte = new List<ISPReg>();
            List<uint> bootSet = new List<uint>();//模式不同
            foreach (var item in listFile)
            {
                if (!string.IsNullOrEmpty(item))
                {

                    //if (item.Contains("{")|| item.Contains("#region")||item.Contains("}")|| (item.Length>= 2&& item.Substring(0, 2).Contains("//")))
                    //{
                    //    continue;
                    //}
                    if ((item.Length >= 2 && item.Substring(0, 2).Contains("0x")))
                    {
                        var listReg = Regex16ToString(item);
                        if (listReg.Count >= 2)
                        {
                            listByte.Add(new ISPReg() { addr = Convert.ToUInt32(listReg[0], 16), value = Convert.ToUInt32(listReg[1], 16) });
                        }
                    }
                }
            }
            //用来验证文件
            //StringBuilder sb = new StringBuilder();
            //for (int i = 0; i < listByte.Count; i++)
            //{
            //    sb.Append($"0x{listByte[i].addr.ToString("x4")},0x{listByte[i].value.ToString("x2")},\r\n");
            //}
            //File.WriteAllText(outputfile, sb.ToString());

            MakeBootSet(listByte, ref bootSet);
            InsCrcCheck(listByte, ref bootSet);
            WriteBootSet(outputfile, listByte, ref bootSet,setHex);
        }


        #endregion

        #region Setting 转Bin

        /// <summary>
        /// setting 转Bin 
        /// </summary>
        /// <param name="outputfile">输出文件</param>
        /// <param name="fsmList">地址 和文件 集合</param>
        /// <param name="model">大小端</param>
        /// <param name="isRandom">是否随机码</param>
        public static void FlashSetting2Bin(string outputfile, List<FlashSettingModel> fsmList, int model = 0, bool isRandom = false ,string binName = null)
        {
            try
            {
                string pSavePath = System.IO.Path.GetDirectoryName(outputfile); //获取文件路径
                string pLocalName = System.IO.Path.GetFileName(outputfile); //获取文件名
                List<FlashSettingModel> fsmTempList = new List<FlashSettingModel>();
                Random rd = new Random();
                for (int i = 0; i < fsmList.Count; i++)
                {
                    FlashSettingModel modelTemp = new FlashSettingModel();
                    modelTemp.fileAddr = fsmList[i].fileAddr;
                    modelTemp.fileLength = fsmList[i].fileLength;
                    modelTemp.fileName = fsmList[i].fileName;
                    modelTemp.fByte = new List<byte>();

                    var addr1 = getUintToString(fsmList[i].fileAddr);
                    //var addr2 = getUintToString(fsmList[i + 1].fileAddr);

                    var flength = getUintToString(fsmList[i].fileLength);


                    string fpathName = string.Empty;
                    /*                    if (!fsmList[i].fileName.Contains(pSavePath)) //判断文件路径是否和生成路径一致   兼容以前代码逻辑
                                        {
                                            fpathName = $"{pSavePath}\\{System.IO.Path.GetFileName(fsmList[i].fileName)}";
                                        }
                                        else*/
                    {
                        fpathName = fsmList[i].fileName;
                    }
                    //var fpath = HeaderHelper.FilePathLength(fpathName); //取消读取文件  存在空格也算长度  故取消使用读取文件长度  但是可以作为参考
                    //var fData = File.ReadAllText(fpathName);

                    List<string> tempStrList = FileProcessing(fpathName);
                    //var fList = fData.Replace("\n", "").Replace("\r","").Replace(" ","").Split(',');                   
                    var fList = tempStrList.ToArray();
                    if (i == 0)//首地址
                    {
                        var addrTemp = addr1 - 0x0000;
                        for (int x = 0; x < addrTemp / 4; x++) //填补空缺
                        {
                            byte[] bTemp = new byte[4];
                            bTemp[0] = Convert.ToByte(rd.Next(0, 255));
                            bTemp[1] = Convert.ToByte(0);
                            bTemp[2] = Convert.ToByte(rd.Next(0, 255));
                            bTemp[3] = Convert.ToByte(rd.Next(0, 255));
                            modelTemp.fByte.AddRange(bTemp);
                        }
                        for (int x = 0; x < addrTemp % 4; x++)//地址是基数地址时添加到起始位置
                        {
                            modelTemp.fByte.Add(Convert.ToByte(rd.Next(0, 255)));
                        }
                    }
                    else
                    {
                        if ((i + 1 < fsmList.Count)) //这里确定是用下个地址的
                        {
                            var addr2 = getUintToString(fsmList[i + 1].fileAddr);
                            flength = addr2 - addr1;
                            modelTemp.fileLength = flength.ToString("X4");
                        }
                    }


                    //1.0 读取文件内容存入
                    foreach (var item in fList)
                    {
                        byte[] bTemp = new byte[4];

                        if (!string.IsNullOrEmpty(item))
                        {
                            var tempUint = getUintToString(item);
                            if (model == 0)
                            {
                                bTemp[0] = (byte)(tempUint & 0xff);
                                bTemp[1] = (byte)(tempUint >> 8 & 0xff);
                                bTemp[2] = (byte)(tempUint >> 16 & 0xff);
                                bTemp[3] = (byte)(tempUint >> 24 & 0xff);
                            }
                            else
                            {
                                bTemp[3] = (byte)(tempUint & 0xff);
                                bTemp[2] = (byte)(tempUint >> 8 & 0xff);
                                bTemp[1] = (byte)(tempUint >> 16 & 0xff);
                                bTemp[0] = (byte)(tempUint >> 24 & 0xff);
                            }
                            modelTemp.fByte.AddRange(bTemp);
                        }
                    }
                    UInt32 ftemp = Convert.ToUInt32(modelTemp.fByte.Count());
                    if (isRandom) //不添加随机码  添加0xff
                    {
                        /**  随机码处理方式：
                              1.头文件  随机码 + 加头文件 + 随机码
                              2.除头文件以为 随机码 + 剩余空间 （下一个文件大小的*0.5 递归）
                        **/

                        //计算需要填补的空间
                        var cadd = (flength - ftemp);
                        if (i == 0)
                        {
                            if (cadd > ftemp)
                            {
                                var tempfByte = new List<byte>(modelTemp.fByte);
                                cadd = cadd - ftemp;
                                var rdTemp = rd.Next(0, Convert.ToInt32(cadd.ToString()));
                                while (!(rdTemp % 4 == 0))
                                {
                                    rdTemp = rd.Next(0, Convert.ToInt32(cadd.ToString()));
                                }
                                if (rdTemp > 0)
                                {
                                    for (int p = 0; p < rdTemp / 4; p++)
                                    {
                                        byte[] bTemp = new byte[4];
                                        bTemp[0] = Convert.ToByte(rd.Next(0, 255));
                                        bTemp[1] = Convert.ToByte(0);
                                        bTemp[2] = Convert.ToByte(rd.Next(0, 255));
                                        bTemp[3] = Convert.ToByte(rd.Next(0, 255));
                                        modelTemp.fByte.AddRange(bTemp);
                                    }
                                }

                                cadd = cadd - Convert.ToUInt32(rdTemp.ToString());
                                modelTemp.fByte.AddRange(tempfByte);
                            }
                            else
                            {
                                var headCount = ftemp / 2;
                                while (headCount > cadd)
                                {
                                    headCount = headCount / 2;
                                }
                                while (!(headCount % 4 == 0))
                                {
                                    headCount++;
                                }
                                modelTemp.fByte.AddRange(modelTemp.fByte.Take(Convert.ToInt32(headCount.ToString())).ToList());
                                cadd = cadd - Convert.ToUInt32(headCount.ToString());
                            }
                        }
                        else
                        {
                            if ((i + 1) < fsmList.Count)
                            {
                                var nextPath = $"{pSavePath}\\{System.IO.Path.GetFileName(fsmList[i + 1].fileName)}";
                                var fnextpath = FilePathLength(nextPath);
                                var headCount = Convert.ToUInt32(fnextpath, 16);
                                while (headCount > cadd)
                                {
                                    headCount = headCount / 2;
                                }
                                while (!(headCount % 4 == 0))
                                {
                                    headCount++;
                                }
                                cadd = cadd - Convert.ToUInt32(headCount);
                                //var fDataT = File.ReadAllText($"{pSavePath}\\{System.IO.Path.GetFileName(fsmList[i + 1].fileName)}");
                                //var fListT = fDataT.Replace("\n", "").Replace("\r", "").Replace(" ", "").Split(',');
                                List<string> fDataT = FileProcessing($"{pSavePath}\\{System.IO.Path.GetFileName(fsmList[i + 1].fileName)}");
                                var fListT = fDataT.ToArray();

                                foreach (var item in fListT)
                                {
                                    if (headCount <= 0)
                                    {
                                        continue;
                                    }
                                    byte[] bTemp = new byte[4];
                                    if (!string.IsNullOrEmpty(item))
                                    {
                                        var tempUint = getUintToString(item);
                                        if (model == 0)
                                        {
                                            bTemp[0] = (byte)(tempUint & 0xff);
                                            bTemp[1] = (byte)(tempUint >> 8 & 0xff);
                                            bTemp[2] = (byte)(tempUint >> 16 & 0xff);
                                            bTemp[3] = (byte)(tempUint >> 24 & 0xff);
                                        }
                                        else
                                        {
                                            bTemp[3] = (byte)(tempUint & 0xff);
                                            bTemp[2] = (byte)(tempUint >> 8 & 0xff);
                                            bTemp[1] = (byte)(tempUint >> 16 & 0xff);
                                            bTemp[0] = (byte)(tempUint >> 24 & 0xff);
                                        }
                                        modelTemp.fByte.AddRange(bTemp);
                                        headCount -= 4;
                                    }
                                }
                            }
                            else
                            {
                                var headCount = ftemp / 2;
                                while (headCount > cadd)
                                {
                                    headCount = headCount / 2;
                                }
                                while (!(headCount % 4 == 0))
                                {
                                    headCount++;
                                }
                                modelTemp.fByte.AddRange(modelTemp.fByte.Take(Convert.ToInt32(headCount.ToString())).ToList());
                                cadd = cadd - Convert.ToUInt32(headCount.ToString());
                            }
                        }

                        for (int z = 0; z < cadd / 4; z++)
                        {
                            byte[] bTemp = new byte[4];
                            bTemp[0] = Convert.ToByte(rd.Next(0, 255));
                            bTemp[1] = Convert.ToByte(0);
                            bTemp[2] = Convert.ToByte(rd.Next(0, 255));
                            bTemp[3] = Convert.ToByte(rd.Next(0, 255));
                            modelTemp.fByte.AddRange(bTemp);
                        }
                    }
                    else
                    {
                        //var ftemp = Convert.ToUInt32(fpath, 16);
                        var cadd = (flength - ftemp);
                        //后期需要修改
                        if (cadd < ftemp)
                        {
                            for (uint j = 0; j < cadd; j++)
                            {
                                modelTemp.fByte.Add(0xff);
                            }
                        }
                    }

                    //这里将TVE的bin名称存入扰码中
                    if (i == 0 && !string.IsNullOrEmpty(binName))
                    {
                        var hex = AppHelper.StringToUTF8(System.IO.Path.GetFileName(binName));
                        int tempNo = 0x400;
                        for (int z = 0; z < hex.Length; z += 2)
                        {
                            if (z == 0)
                            {
                                modelTemp.fByte[tempNo] = 0x12;
                                tempNo++;
                                modelTemp.fByte[tempNo] = 0x34;
                                tempNo++;
                                modelTemp.fByte[tempNo] = 0x56;
                                tempNo++;
                                modelTemp.fByte[tempNo] = 0x78;
                                tempNo++;
                                modelTemp.fByte[tempNo] = Convert.ToByte(hex.Length >> 24 & 0xFF);
                                tempNo++;
                                modelTemp.fByte[tempNo] = Convert.ToByte(hex.Length >> 16 & 0xFF);
                                tempNo++;
                                modelTemp.fByte[tempNo] = Convert.ToByte(hex.Length >> 8 & 0xFF);
                                tempNo++;
                                modelTemp.fByte[tempNo] = Convert.ToByte(hex.Length & 0xFF);
                                tempNo++;
                            }
                            // 将每两个字符的十六进制字符串转换为byte  
                            modelTemp.fByte[tempNo] = Convert.ToByte(hex.Substring(z, 2), 16);
                            tempNo++;
                        }
                    }
                    fsmTempList.Add(modelTemp);
                }

                List<byte> bListByte = new List<byte>();
                foreach (var item in fsmTempList)
                {
                    //检查长度是否到达
                    if (item.fByte.Count() < Convert.ToInt32(item.fileLength, 16))
                    {
                        var bTemp = Convert.ToInt32(item.fileLength, 16) - item.fByte.Count();
                        for (int z = 0; z < bTemp; z++)
                        {
                            item.fByte.Add(Convert.ToByte(rd.Next(0, 255)));
                        }
                    }
                    bListByte.AddRange(item.fByte);
                }
                File.WriteAllBytes(outputfile, bListByte.ToArray());
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        private static UInt32 getUintToString(string addr)
        {
            if (string.IsNullOrEmpty(addr))
            {
                return 0x0;
            }
            else if (addr.Contains("0x"))
            {
                var temp = addr.Replace("0x", "").Trim();
                return Convert.ToUInt32(temp, 16);
            }
            else
            {

                return Convert.ToUInt32(addr.Trim(), 16);
            }
        }
        public static List<string> FileProcessing(string fpathName)
        {
            #region 处理flash文件，去除注释、逗号、0x
            StreamReader sr = new StreamReader(fpathName);
            string tempStr = string.Empty;
            List<string> tempStrList = new List<string>();
            while ((tempStr = sr.ReadLine()) != null)
            {
                if (tempStr.Contains("//"))
                {
                    var index = tempStr.IndexOf("//");
                    tempStr = tempStr.Remove(index);
                }
                tempStr = tempStr.Trim().Replace(",", "").Replace("，", "").Replace("0x", "");
                List<string> listStr = Regex32ToString(tempStr);
                if (null != listStr && listStr.Count > 0)
                {
                    tempStr = listStr.First();
                    tempStrList.Add(tempStr);
                }
            }
            sr.Close();

            #endregion
            return tempStrList;
        }
        public static string FilePathLength(string mpath)
        {
            int tempLength = File.ReadAllLines(mpath).Length;
            return (tempLength * 4).ToString("x4");
        }
        public static List<string> Regex32ToString(string reg)
        {
            var strlist = new List<string>();
            Regex ConnoteA = new Regex("[a-fA-F0-9]{8}");
            foreach (var item in ConnoteA.Matches(reg))
            {
                strlist.Add(item.ToString());
            }
            return strlist;
        }
        #endregion


        #region 文件处理

        public static List<string> ReadTextFileToList(string fileName)
        {
            List<string> list = new List<string>();

            FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);

            StreamReader sr = new StreamReader(fs);
            //使用StreamReader类来读取文件 
            sr.BaseStream.Seek(0, SeekOrigin.Begin);
            // 从数据流中读取每一行，直到文件的最后一行
            string tmp = sr.ReadLine();
            while (tmp != null)
            {
                list.Add(tmp.ToLower());
                tmp = sr.ReadLine();
            }
            //关闭此StreamReader对象 
            sr.Close();
            fs.Close();
            return list;
        }


        public static List<string> Regex16ToString(string reg)
        {
            var strlist = new List<string>();
            Regex ConnoteA = new Regex("(0x)[a-fA-F0-9]{1,4}");
            foreach (var item in ConnoteA.Matches(reg.ToLower()))
            {
                strlist.Add(item.ToString().Replace("0x", "").Replace(" ", "").ToLower());
            }
            return strlist;
        }

        #endregion

        #region 主方法
        public static void MakeBootSet(List<ISPReg> listByte, ref List<uint> bootSet)
        {
            //1.为头文件进行位置预留
            for (int m = 0; m < 4; m++)
            {
                bootSet.Add(0x00);
            }
            //bool lianxieStartMask = false;//连写启动模式
            int i = 0;
            while (i < listByte.Count)
            {
                if (IsNoKey)
                {
                    i += Mode_ISP(i, listByte, ref bootSet);
                    continue;
                }
                if (I2cLianXie)
                {
                    if (listByte[i].addr == 0xfff0 || listByte[i].addr == 0xfff8)
                    {
                        I2C_addr = (UInt16)listByte[i].value;
                        i++;
                    }
                    //修改IIC模式
                    else if ((listByte[i].addr == 0xfff1))
                    {
                        //I2C_mode = regs[i].value;
                        Mode_0xFFF1(i, listByte);
                        //Mode_0xfff1(i);
                        i++;
                    }
                    //度信外部模式下，修改IIC模式
                    else if ((listByte[i].addr == 0xfffe) && (listByte[i - 1].addr == 0xfff8))
                    {
                        Mode_0xFFF1(i, listByte);
                        //mode_0xfff1(i);
                        i++;
                    }
                    else if (listByte[i].addr == 0xfff2)
                    {
                        if (listByte[i].value == 0x01)
                        {
                            I2cLianXie = true;
                        }
                        else if (listByte[i].value == 0x0)
                        {
                            I2cLianXie = false;
                        }
                        else
                        {
                            bootSet.Add(Convert.ToUInt32((0xfff2 << 16) + listByte[i].value));
                        }
                        i++;
                    }
                    else
                    {
                        if (I2cLianXie)
                        {
                            i += Mode_Sensor(i, listByte, ref bootSet);
                        }
                        else
                        {
                            i += Mode_ISP(i, listByte, ref bootSet);
                        }
                    }
                }
                else if (listByte[i].addr == 0xfff2)
                {
                    if (listByte[i].value == 0x01)
                    {
                        I2cLianXie = true;
                    }
                    else if (listByte[i].value == 0x0)
                    {
                        I2cLianXie = false;
                    }
                    else
                    {
                        bootSet.Add(Convert.ToUInt32((0xfff2 << 16) + listByte[i].value));
                    }
                    i++;
                }
                //修改度信模式
                else if (listByte[i].addr == 0xffff)
                {
                    Mode_OxFFFF(i, listByte, ref bootSet);
                    i++;
                }
                //修改IIC地址
                else if (listByte[i].addr == 0xfff0 || listByte[i].addr == 0xfff8)
                {
                    if (I2cLianXie)
                    {
                        //lianxieStartMask = true;
                        duxin_mode = 0;
                    }
                    I2C_addr = (UInt16)listByte[i].value;
                    i++;
                }//修改IIC模式
                else if ((listByte[i].addr == 0xfff1))
                {
                    //I2C_mode = regs[i].value;
                    //mode_0xfff1(i);
                    Mode_0xFFF1(i, listByte);
                    i++;
                }//度信外部模式下，修改IIC模式
                else if ((duxin_mode == 0) && (listByte[i].addr == 0xfffe))
                {
                    Mode_0xFFF1(i, listByte);
                    i++;
                }//FFFD Mode
                else if (listByte[i].addr == 0xfffd)
                {
                    bootSet.Add(Convert.ToUInt32((listByte[i].addr << 16) + listByte[i].value));
                    i++;
                }//修改ISP高24位地址
                else if (listByte[i].addr == 0xfffe)
                {
                    Mode_0xFFFE(i, listByte, ref bootSet);

                    //mode_0xfffe(i);
                    i++;
                }//版本需求问题，不再使用此模式
                 //else if (listByte[i].addr == 0xfff5)
                 //{
                 //    //mode_0xfff5(i);
                 //    Mode_0xFFF5(i, listByte, ref bootSet);
                 //    i++;
                 //}

                //对ISP进行配置时
                else if ((I2C_addr == 0x36) || (I2C_addr == 0x38))
                {
                    i += Mode_ISP(i, listByte, ref bootSet);
                }
                //Sensor模式
                else
                {
                    if (I2cLianXie)
                    {
                        i += Mode_Sensor(i, listByte, ref bootSet);
                    }
                    else
                    {
                        i += Mode_ISP(i, listByte, ref bootSet);
                    }
                }
            }

        }

        public static void WriteBootSet(string outputfile, List<ISPReg> listByte,ref List<uint> bootSet, uint setHex = 0x0)
        {
            uint XCHIP = 0x58430151;
            bootSet[0] = (XCHIP);
            //长度值反转，矫正CRC校验,注释掉是因为在crc_check函数李做了大小端处理;
            bootSet[1] = (Convert.ToUInt32(bootSet.Count));
            bootSet[2] = ((uint)((0xfff5 << 16) + crc_check(0, 2, listByte, bootSet)));
            bootSet[0] = (XCHIP_ID);
            string str = bootSet[1].ToString("X8");
            string ccc1 = str.Substring(0, 2);
            string ccc11 = str.Substring(2, 2);
            string ccc111 = str.Substring(4, 2);
            string ccc1111 = str.Substring(6);
            string newstr2 = ccc1111 + ccc111 + ccc11 + ccc1;
            uint boot_str = (uint)Convert.ToInt32(newstr2, 16);
            bootSet[1] = boot_str;
            bootSet[3] = setHex; //新增 用于存储视频格式、制式、顺序
            //大小端反转需要修改上面的XCHIP_ID
            if (Model == 0)
            {
                //StringBuilder sb = new StringBuilder();
                //for (int i = 0; i < bootSet.Count; i++)
                //{
                //    sb.Append($"0x{(i * 4 + E2promMode).ToString("x4")},0x{(bootSet[i] >> 24 & 0xff).ToString("x2")},\n");
                //    sb.Append($"0x{(i * 4 + 1 + E2promMode).ToString("x4")},0x{(bootSet[i] >> 16 & 0xff).ToString("x2")},\n");
                //    sb.Append($"0x{(i * 4 + 2 + E2promMode).ToString("x4")},0x{(bootSet[i] >> 8 & 0xff).ToString("x2")},\n");
                //    sb.Append($"0x{(i * 4 + 3 + E2promMode).ToString("x4")},0x{(bootSet[i] & 0xff).ToString("x2")},\n");
                //}

                //File.WriteAllText(outputfile, sb.ToString());

                string newstr = "";
                //StringBuilder sb = new StringBuilder();
                int i = 0;
                foreach (var item in bootSet)
                {
                    if (i > 1)
                    {
                        string aa = item.ToString("x8");
                        string cc1 = aa.Substring(0, 2);
                        string cc11 = aa.Substring(2, 2);
                        string cc111 = aa.Substring(4, 2);
                        string cc1111 = aa.Substring(6);
                        newstr += cc1111 + cc111 + cc11 + cc1 + "\r\n";
                    }
                    else
                    {
                        string aa = item.ToString("x8");
                        newstr += aa + "\r\n";
                        i++;
                    }

                    //sb.Append($"0x{item.ToString("x8")},\n");
                }
                File.WriteAllText(outputfile, newstr);
            }
            else
            {
                StringBuilder sb = new StringBuilder();
                foreach (var item in bootSet)
                {
                    sb.Append($"0x{item.ToString("x8")},\n");
                }
                File.WriteAllText(outputfile, sb.ToString());
            }
        }
        static int CRCCHECKNUM = 256;
        static uint CRCKEYWORD = 0xf6f5;
        public static void InsCrcCheck(List<ISPReg> listByte, ref List<uint> bootSet)
        {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < bootSet.Count; i++)
            {
                sb.Append($"0x{bootSet[i].ToString("x8")},\r\n");
            }
            //File.WriteAllText("C:\\Users\\Administrator\\Desktop\\insCrcCheck22.txt", sb.ToString());


            int count = bootSet.Count;       //由于setCount的值会改变，故使用temp作为计数
            //int CRCCHECKNUM = 128;
            //int arry[CRCCHECKNUM * 11]; //用于存放校验值的数组
            List<int> arry = new List<int>();
            int check_num = (count - 4) / (CRCCHECKNUM / 4);    //单次校验数

            //1.从有效数据开始，每CRCCHECKNUM/4为一组，进行crc校验，并将所有校验值按顺序写入数组arry中
            for (int i = 0; i < check_num; i++)
            {
                int a = 4 + (CRCCHECKNUM / 4) * i;
                arry.Add(crc_check(4 + (CRCCHECKNUM / 4) * i, (CRCCHECKNUM / 4), listByte, bootSet));
            }
            //2.将余下不足CRCCHECKNUM/4的数据进行数据补齐并校验插值
            int alignment = (count - 4) % (CRCCHECKNUM / 4);
            if (alignment != 0)
            {
                int bef_end = (check_num) * (CRCCHECKNUM / 4) + 4;
                for (int i = 0; i < (CRCCHECKNUM / 4) - alignment; i++)
                {
                    bootSet.Add(0xfff70000);
                    //WriteReg(0xfff70000);
                }

                InsValue(bef_end, (uint)((CRCKEYWORD << 16) + crc_check(bef_end, (CRCCHECKNUM / 4), listByte, bootSet)), listByte, ref bootSet); //CRC关键字 0xf5f5 
            }
            //3.将arry中的值按顺序插入正确的地址
            for (int i = 0; i < check_num; i++)
            {
                InsValue(4 + (CRCCHECKNUM / 4 + 1) * (i), (uint)((CRCKEYWORD << 16) + arry[i]), listByte, ref bootSet); //CRC关键字 0xf5f5  CRC校验128
            }
        }

        public static void InsValue(int addr, uint value, List<ISPReg> listByte, ref List<uint> bootSet)
        {
            if (addr < 0) return;
            for (int i = bootSet.Count; i >= addr; i--)
            {
                if ((i + 1) > bootSet.Count)
                {
                    bootSet.Add(bootSet[i - 1]);
                }
                else
                {
                    bootSet[i + 1] = bootSet[i];
                }
            }
            bootSet[addr] = value;
        }

        #endregion

        #region Mode

        public static int Mode_ISP(int count, List<ISPReg> listByte, ref List<uint> bootSet)
        {
            if (IsNoKey)
            {
                bootSet.Add((listByte[count].addr << 16) + listByte[count].value);
                return 1;
            }
            if (ISP_top == 0x50 && listByte[count].addr == 0x4d)
            {
                ////临时处理将该段代码注掉;
                //if ((listByte[count].value & 0x01) == 0x01)
                //{
                //    listByte[count].value &= 0xFE;

                //}
                bootSet.Add((listByte[count].addr << 16) + listByte[count].value);
                return 1;
            }
            else if (ISP_top == 0xff)
            {
                if (Usage)
                {
                    bootSet.Add((listByte[count].addr << 16) + listByte[count].value);
                }
                return 1;
            }
            else if (count + 1 < listByte.Count && (listByte[count].addr + 1) == (listByte[count + 1].addr)) //普通寄存器连写模式更改
            {
                /* */
                int groups_num = 1;
                List<string> keywords = new List<string> { "F4F5", "F5F5", "F6F5", "FFFF", "FFFE", "FFFD", "FFF6", "FFF7" };
                while (count + 1 < listByte.Count && ((listByte[count].addr + 1) == (listByte[count + 1].addr)))
                {
                    if (listByte[count].addr.ToString("x2").Contains("7c84"))
                    {

                    }
                    if (keywords.Contains($"{listByte[count].value.ToString("X2")}{listByte[count + 1].value.ToString("X2")}"))
                    {
                        break;
                    }
                    groups_num++;
                    count++;
                }
                count++;
                //if (count >70)
                //{

                //}

                if (groups_num < 4)
                {
                    //小于4启动正常模式
                    for (int i = groups_num; i > 0; i--)
                    {
                        bootSet.Add((listByte[count - i].addr << 16) + listByte[count - i].value);
                    }
                }
                else
                {
                    //大于等于4启动连写模式
                    Contiuous_Mode((count - groups_num), groups_num, listByte, ref bootSet);
                }
                return groups_num;
            }
            else
            {
                bootSet.Add((listByte[count].addr << 16) + listByte[count].value);
                return 1;
            }
            //return 0;
        }

        static int CRCFUN = 64;
        static void Contiuous_Mode(int start, int num, List<ISPReg> listByte, ref List<uint> bootSet)
        {

            int i = 0; uint temp = 0;
            //128 对应32行  256对应64行
            //判断bootset 到crc 还存在多少空间   bootset 空了4行  减去 2行 fff8 fff9
            //空间足够
            //头部空间 只够存放 8个字节 补 fff7
            //最后一包数据  补足256 补 fff7  64*4 =256  - 8  =248 /4 = 62  最大62行  最小 3行
            // 处理num ＞248 需要处理 数据


            var crcCap = (CRCFUN - ((bootSet.Count - 4) % CRCFUN)) - 2;
            if (crcCap <= 0)
            {
                for (int r = 0; r < Math.Abs(crcCap); r++)
                {
                    bootSet.Add((0xfff70000));
                }
                if (crcCap == 0)
                {
                    //补充两行无用数据  跳过crc校验
                    bootSet.Add((0xfff70000));
                    bootSet.Add((0xfff70000));
                }
                crcCap = (CRCFUN - ((bootSet.Count - 4) % CRCFUN)) - 2;
            }

            //计算num 需要多少个256的空间 256-8 的空间
            var crcNo = Math.Ceiling(num / 4.0);  //计算所需要的行  超出就入


            if (crcCap == crcNo)
            {
                //bootSet.Add((uint)((0xfff8 << 16) + crcCap * 4));
                var  lenf8 = (((int)(num / 4) * 4) + (num % 4.0));
                bootSet.Add((uint)((0xfff8 << 16) + lenf8));
                bootSet.Add((uint)((0xfff9 << 16) + listByte[start].addr));
                if (listByte[start].addr.ToString("x2").Contains("2300"))
                {

                }
                for (int j = 0; j < num / 4; j++)
                {
                    bootSet.Add((listByte[start + j * 4 + 0].value << 24)
                       + (listByte[start + j * 4 + 1].value << 16)
                       + (listByte[start + j * 4 + 2].value << 8)
                       + (listByte[start + j * 4 + 3].value));
                }
                if ((num % 4) != 0)
                {
                    for (i = 0; i < (num % 4); i++)
                    {
                        temp += (listByte[start + (num / 4) * 4 + i].value << (24 - i * 8));
                    }
                    bootSet.Add(temp);
                }
            }
            else if (crcNo > crcCap) //表示需要分成两个部分  
            {
                if (listByte[start].addr.ToString("x2").Contains("2300"))
                {

                }
                bootSet.Add((uint)((0xfff8 << 16) + crcCap * 4));
                bootSet.Add((uint)((0xfff9 << 16) + listByte[start].addr));
                for (int j = 0; j < crcCap; j++)
                {
                    bootSet.Add((listByte[start + j * 4 + 0].value << 24)
                       + (listByte[start + j * 4 + 1].value << 16)
                       + (listByte[start + j * 4 + 2].value << 8)
                       + (listByte[start + j * 4 + 3].value));
                }
                var crcFN = (int)((crcNo - crcCap) / (CRCFUN - 2));
                if (crcFN <= 0)
                {
                    //var crcTemp = (int)(crcNo - crcCap) * 4;
                    var lengthTemp = num - (crcCap * 4);
                    var startcrc = start + crcCap * 4;
                    bootSet.Add((uint)((0xfff8 << 16) + Convert.ToUInt32(lengthTemp)));
                    bootSet.Add((uint)((0xfff9 << 16) + listByte[startcrc].addr));
                    if (listByte[startcrc].addr.ToString("x2").Contains("01e9"))
                    {

                    }
                    for (int j = 0; j < lengthTemp / 4; j++)
                    {
                        bootSet.Add((listByte[startcrc + j * 4 + 0].value << 24)
                           + (listByte[startcrc + j * 4 + 1].value << 16)
                           + (listByte[startcrc + j * 4 + 2].value << 8)
                           + (listByte[startcrc + j * 4 + 3].value));
                    }

                    if ((lengthTemp % 4) != 0)
                    {
                        for (i = 0; i < (lengthTemp % 4); i++)
                        {

                            temp += (listByte[startcrc + (lengthTemp / 4) * 4 + i].value << (24 - i * 8));
                        }
                        bootSet.Add(temp);
                    }
                }
                else
                {
                    var crcN_C = (num - crcCap * 4); //剩余的需要添加的数目
                    var startcrc = start + crcCap * 4;
                    for (int z = 0; z < crcFN; z++)
                    {
                        if (listByte[startcrc].addr.ToString("x2").Contains("2300"))
                        {

                        }
                        if (crcN_C - 248 > 0)
                        {

                            bootSet.Add((uint)((0xfff8 << 16) + ((CRCFUN - 2) * 4)));
                            bootSet.Add((uint)((0xfff9 << 16) + listByte[startcrc].addr));
                            for (int j = 0; j < 62; j++)
                            {
                                bootSet.Add((listByte[startcrc + j * 4 + 0].value << 24)
                              + (listByte[startcrc + j * 4 + 1].value << 16)
                              + (listByte[startcrc + j * 4 + 2].value << 8)
                              + (listByte[startcrc + j * 4 + 3].value));
                            }
                            startcrc += 248;
                            crcN_C -= 248;
                        }

                    }

                    if (crcN_C >= 248)
                    {
                        bootSet.Add((uint)((0xfff8 << 16) + ((CRCFUN - 2) * 4)));
                        bootSet.Add((uint)((0xfff9 << 16) + listByte[startcrc].addr));
                        if (listByte[startcrc].addr.ToString("x2").Contains("2300"))
                        {

                        }
                        for (int j = 0; j < 62; j++)
                        {
                            bootSet.Add((listByte[startcrc + j * 4 + 0].value << 24)
                          + (listByte[startcrc + j * 4 + 1].value << 16)
                          + (listByte[startcrc + j * 4 + 2].value << 8)
                          + (listByte[startcrc + j * 4 + 3].value));
                        }
                        startcrc += 248;
                        crcN_C -= 248;
                    }
                    if (crcN_C > 0)
                    {
                        bootSet.Add((uint)((0xfff8 << 16) + (crcN_C)));
                        bootSet.Add((uint)((0xfff9 << 16) + listByte[startcrc].addr));
                        if (listByte[startcrc].addr.ToString("x2").Contains("2300"))
                        {

                        }
                        for (int j = 0; j < crcN_C / 4; j++)
                        {
                            bootSet.Add((listByte[startcrc + j * 4 + 0].value << 24)
                          + (listByte[startcrc + j * 4 + 1].value << 16)
                          + (listByte[startcrc + j * 4 + 2].value << 8)
                          + (listByte[startcrc + j * 4 + 3].value));
                        }

                        if ((crcN_C % 4) != 0)
                        {
                            for (i = 0; i < (crcN_C % 4); i++)
                            {
                                temp += (listByte[startcrc + (crcN_C / 4) * 4 + i].value << (24 - i * 8));
                            }
                            bootSet.Add(temp);
                        }
                    }
                }




            }
            else
            {
                bootSet.Add((uint)((0xfff8 << 16) + num));
                bootSet.Add((uint)((0xfff9 << 16) + listByte[start].addr));

                for (i = 0; i < num / 4; i++)
                {
                    bootSet.Add((listByte[start + i * 4 + 0].value << 24)
                        + (listByte[start + i * 4 + 1].value << 16)
                        + (listByte[start + i * 4 + 2].value << 8)
                        + (listByte[start + i * 4 + 3].value));
                }
                if ((num % 4) != 0)
                {
                    for (i = 0; i < (num % 4); i++)
                    {

                        temp += (listByte[start + (num / 4) * 4 + i].value << (24 - i * 8));
                    }
                    bootSet.Add(temp);
                }

            }




        }

        public static void Mode_OxFFFF(int count, List<ISPReg> listByte, ref List<uint> bootSet)
        {
            if (listByte[count].value == 0xfef1)
            {
                duxin_mode = 1;
            }
            else if (listByte[count].value == 0xfef0)
            {
                duxin_mode = 0;
            }
            else
            {
                //var temp = (0xffff << 16) + (listByte[count].value);
                bootSet.Add((uint)((0xffff << 16) + (listByte[count].value)));
            }
        }
        public static void Mode_0xFFF1(int count, List<ISPReg> listByte)
        {
            if ((listByte[count].value == 0) || (listByte[count].value == 1))
            {
                I2C_mode = 0;
            }
            else if (listByte[count].value == 3|| listByte[count].value == 2)
            {
                I2C_mode = 1;
            }
            else if (listByte[count].value == 4)
            {
                I2C_mode = 2;
            }
            else if (listByte[count].value == 5)
            {
                I2C_mode = 5;
            }
            else if (listByte[count].value == 6)
            {
                I2C_mode = 6;
            }
            else if (listByte[count].value == 7)
            {
                I2C_mode = 7;
            }
        }

        public static void Mode_0xFFFE(int count, List<ISPReg> listByte, ref List<uint> bootSet)
        {
            if (duxin_mode == 0)
            {
                I2C_mode = (UInt16)listByte[count].value;
            }
            else
            {
                ISP_top = (UInt16)listByte[count].value;
                if (ISP_top == 0xff)
                {
                    if (Usage)
                    {
                        bootSet.Add(Convert.ToUInt32((listByte[count].addr << 16) + listByte[count].value));
                    }
                }
                else
                {
                    bootSet.Add(Convert.ToUInt32((listByte[count].addr << 16) + listByte[count].value));
                }
            }
        }
        
        public static int Mode_Sensor(int count, List<ISPReg> listByte, ref List<uint> bootSet)
        {
            int sensor_nums = 0;
            //用于记录32a的长度
            int forsum = 0;
            //在bin文件里I2C_mode567对应345
            if (I2C_mode == 5 || I2C_mode == 6 || I2C_mode == 7)
            {
                bootSet.Add((uint)((0xfff6 << 16) + (I2C_addr << 8) + I2C_mode -2));
            }
            else
            {
                bootSet.Add((uint)((0xfff6 << 16) + (I2C_addr << 8) + I2C_mode));
            }
            uint sensor_make = Convert.ToUInt32(bootSet.Count());	//缓存SensorSetting地址
            bootSet.Add(0x0);
            if (I2cLianXie)
            {
               
                while ((count + sensor_nums < listByte.Count) && (listByte[sensor_nums + count].addr != 0xfff8) &&
                    (listByte[sensor_nums + count].addr != 0xfff0) &&
                    (listByte[sensor_nums + count].addr != 0xfff1) &&
                    (listByte[sensor_nums + count].addr != 0xfff2) &&
                    (count + sensor_nums < listByte.Count))
                {
                    sensor_nums++;
                }
                
                
            }
            else
            {
                while ((count + sensor_nums < listByte.Count) && (listByte[sensor_nums + count].addr != 0xfffe) &&
                       (listByte[sensor_nums + count].addr != 0xfffd) &&
                       (listByte[sensor_nums + count].addr != 0xfff8) &&
                       (listByte[sensor_nums + count].addr != 0xfff0) &&
                       (listByte[sensor_nums + count].addr != 0xfff1) &&
                       (count + sensor_nums < listByte.Count))
                {
                    sensor_nums++;
                }
            }
            if (I2C_mode == 0)
            {
                for (int i = 0; i < sensor_nums / 2; i++)
                {
                    bootSet.Add(Convert.ToUInt32((listByte[count].addr << 24) +
                    (listByte[count].value << 16) +
                    (listByte[count + 1].addr << 8) +
                    (listByte[count + 1].value)));
                    count += 2;
                }
                if (sensor_nums % 2 != 0)
                {
                    bootSet.Add(Convert.ToUInt32((listByte[count].addr << 24) +
                    (listByte[count].value << 16) +
                    (listByte[count].addr << 8) +
                    (listByte[count].value)));
                }
            }
            else if (I2C_mode == 5)
            {
                for (int i = 0; i < sensor_nums / 3; i++)
                {
                   
                    //var t = (listByte[count].value << 16) + (listByte[count + 1].value);
                    //var t1 = reverseBits(t);
                    bootSet.Add((listByte[count].value << 16) + (listByte[count + 1].value));
                    forsum++;
                    bootSet.Add((listByte[count + 2].value) );
                    forsum++;
                    count += 3;
                }
                //if (sensor_nums % 2 != 0)
                //{
                //    bootSet.Add(Convert.ToUInt32((listByte[count].addr << 24) +
                //    (listByte[count].value << 16) +
                //    (listByte[count].addr << 8) +
                //    (listByte[count].value)));
                //}
            }
            else if (I2C_mode == 6)
            {
                for (int i = 0; i < sensor_nums / 3; i++)
                {

                    //var t = (listByte[count].value << 16) + (listByte[count + 1].value);
                    //var t1 = reverseBits(t);
                    bootSet.Add((listByte[count].value << 16) + (listByte[count + 1].value));
                    forsum++;
                    bootSet.Add((listByte[count + 2].value));
                    forsum++;
                    count += 3;
                    
                }
            }
            else if (I2C_mode == 7)
            {
                for (int i = 0; i < sensor_nums / 4; i++)
                {

                    //var t = (listByte[count].value << 16) + (listByte[count + 1].value);
                    //var t1 = reverseBits(t);
                    bootSet.Add((listByte[count].value << 16) + (listByte[count + 1].value));
                    forsum++;
                    bootSet.Add((listByte[count + 2].value<<16)+ (listByte[count + 3].value ));
                    forsum++;
                    count += 4;
                   
                }
            }
            else
            {
                for (int i = 0; i < sensor_nums; i++)
                {
                    bootSet.Add(Convert.ToUInt32((listByte[count].addr << 16) + listByte[count].value));
                    count++;
                }
            }
            if (I2C_mode == 5 || I2C_mode == 6 || I2C_mode == 7)
            {
                bootSet[Convert.ToInt32(sensor_make)] = (uint)(((0xfff7 << 16) + forsum));
            }
            else
            {
                bootSet[Convert.ToInt32(sensor_make)] = (uint)(((0xfff7 << 16) + sensor_nums));
            }
            
            return sensor_nums;
        }


        #endregion


       static UInt32 reverseBits(UInt32 x)
        {
            var x1 = x.ToString("X4");
           
                
            //var x2 = x1.Reverse().ToString();
            List<string> t = new List<string>();
            for (int i = 0; i < x1.Length; )
            {
                t.Add($"{x1[i]}{x1[i+1]}");
                i += 2;
            }
            //uint y = 0x55555555;
            //x = (((x >> 1) & y) | ((x & y) << 1));
            //y = 0x33333333;
            //x = (((x >> 2) & y) | ((x & y) << 2));
            //y = 0x0f0f0f0f;
            //x = (((x >> 4) & y) | ((x & y) << 4));
            //y = 0x00ff00ff;
            //x = (((x >> 8) & y) | ((x & y) << 8));
            return Convert.ToUInt32($"{t[3]}{t[2]}{t[1]}{t[0]}",16); 
        }

        #region 计算CRC
        /// <summary>
        /// 计算crc
        /// </summary>
        /// <param name="star"></param>
        /// <param name="lengths"></param>
        /// <param name="listByte"></param>
        /// <param name="bootSet"></param>
        /// <returns></returns>
        private static int crc_check(int star, int lengths, List<ISPReg> listByte, List<uint> bootSet)
        {
            if (lengths > 64) //修改成256后 需要修改成64  修改成128 则是32
            {
                return 0;
            }
            List<byte> checkList = new List<byte>();
            for (int i = 0; i < lengths; i++)
            {
                if (Model == 0)//小端计算CRC;
                {
                    checkList.Add((byte)Convert.ToUInt16((bootSet[star + i]) & 0xff));
                    checkList.Add((byte)Convert.ToUInt16((bootSet[star + i] >> 8) & 0xff));
                    checkList.Add((byte)Convert.ToUInt16((bootSet[star + i] >> 16) & 0xff));
                    checkList.Add((byte)Convert.ToUInt16((bootSet[star + i] >> 24) & 0xff));
                }
                else//大端计算CRC;
                {
                    checkList.Add((byte)Convert.ToUInt16((bootSet[star + i] >> 24) & 0xff));
                    checkList.Add((byte)Convert.ToUInt16((bootSet[star + i] >> 16) & 0xff));
                    checkList.Add((byte)Convert.ToUInt16((bootSet[star + i] >> 8) & 0xff));
                    checkList.Add((byte)Convert.ToUInt16((bootSet[star + i]) & 0xff));
                }

            }
            return XchipCrcCheck16(0xFFFF, checkList.ToArray());
        }

        public static UInt16 XchipCrcCheck16(UInt16 Input, byte[] data)
        {
            //string crcstr = "";
            //string tempCountstr = "";
            //string datastr = "";
            //string sumstr = "";
            UInt16 crc_reg = Input;
            for (int i = 0; i < data.Count(); i++)
            {
                var tempCount = (crc_reg ^ data[i]) & 0xff;
                crc_reg = Convert.ToUInt16((crc_reg >> 8) ^ crc16_table[tempCount]);
                //tempCountstr+= tempCount.ToString("x4") + "\r\n";
                //datastr+= data[i].ToString("x4") + "\r\n";
                //crcstr += "crc_reg:" + "0x" + crc_reg.ToString("x4")+"\r\n";
                //sumstr += "crc_reg:" + "0x" + crc_reg.ToString("x4") + " data: 0x" + data[i].ToString("x4") + "\r\n"; ;
            }
            return Convert.ToUInt16(crc_reg & 0xFFFF);
        }
        #endregion
    }

    

}
